from description import *
import os
import re
from core.config import Config
from error import BuildError
REPLACE_COMPRESSION={}
if Config.COMPRESSION>2:
    for ind in Config.REPLACE_COMPRESSION_3:
        REPLACE_COMPRESSION[ind]=Config.REPLACE_COMPRESSION_3[ind]
renameIds={}
renameIds["global"]=[0]
renameString="abcdefghyjklmnopqrstvwxyzABCDEFGHYJKLMNOPQRSTVWXYZ"

SPLIT="([,=\(\) :\!\[\];+\-/\*])"

def translateType(objectType):
    if objectType.find("Vector")==0:
        return "Array"
    elif objectType.find("Dictionary")==0:
        return "Object"
    return objectType 


def sortProperty(a,b):
    if a.objectType=="property" and b.objectType=="method":
        return -1
    elif a.objectType=="method" and b.objectType=="property":
        return 1
    elif a.objectType=="method" and b.objectType=="method" and a.constructor:
        return -1
    elif a.objectType=="method" and b.objectType=="method" and b.constructor:
        return 1
    else:
        return 0
    
protectedID={}

class JSFile:
    def __init__(self,asFile):
        self.protectedID=asFile.protectedID
        self.output=asFile.getFileDescriptions().name+'.'+asFile.getFileDescriptions().value
        self.output=self.output.replace('.','/')+".js"
        self.input=self.output.replace('.js','.as')
        self.asFile=asFile
    
    def write(self):
        #print "name",asFile.getFileDescriptions().name
        #print "value",asFile.getFileDescriptions().value
        
        self._class=JSClass(self.asFile.getFileDescriptions(),self.input,self.asFile.mainScript)
        self._static=JSStatic(self.asFile.getFileDescriptions(),self.input,self.asFile.mainScript)
        self._prototype=JSPrototype(self.asFile.getFileDescriptions(),self.input,self.asFile.mainScript)
        
        
    def getContent(self):
        if Config.COMPRESSION:
            ret=self._class.getResult()+";"+self._static.getResult()+";"+self._prototype.getResult()+";"
        else:
            ret=self._class.getResult()+"\n"+self._static.getResult()+"\n"+self._prototype.getResult()+"\n"
        
        if ret and True:
            for ind in self.protectedID:
                ret=ret.replace(ind,str(self.protectedID[ind]))
        return ret
        
    def getFooter(self):
        if Config.MERGE_FILE:
            return self._class.getFooter()+self._prototype.getFooter()
        else:
            return ""
        
    
    def getOuputPath(self):
        return Config.FOLDER+self.output
    

class JSGeneric:
    def __init__(self,desc,header=False,path_=None,mainScript=False):
        self._path=path_
        self.mainScript=mainScript
        self.className=None
        self.header=header
        self.desc=desc
        self.addline=[]
        self.extends=[]
        self.blockComment=False
        self.result=""
        self.lines=self.write(desc.getChilds())
    
    def getResult(self):
        ret=""
        if Config.COMPRESSION:
            
            for line in self.lines:
                if not line:
                    continue
                
                
                if self.blockComment and line.line.find("*/")>-1:
                    self.blockComment=False
                    line.line=line.line[line.line.find("*/")+2:]
                elif self.blockComment:
                    continue
            
                if line.line.find("//")>-1:
                    line.line=line.line[:line.line.find("//")]
                    
                if line.line.find("/*")>-1:
                    self.blockComment=True
                    line.line=line.line[:line.line.find("/*")]    
                
                if line.line=="":
                    continue
                a=-1
                if line.line[a]!=";" and line.line[a]!="," and line.line[a]!="{" and line.line[a]!=":" and line.line[a]!="}" and line.desc and not line.desc.block:
                    line.line+=";"
                space=["function","new","set","get","var","return","else","if","in","case"]
                spaceBefore=["each","in"]
                spiltSpace=re.split(SPLIT,line.line)#line.line.split(" ")
                result=[]
                prevSpace=False
                cpt=0
                for word in spiltSpace:
                    #pass
                    if word==" ":
                        try:
                            space.index(spiltSpace[cpt-1])
                            if spiltSpace[cpt-1]=="function" and spiltSpace[cpt+1]=="(":
                                continue
                            result.append(word)
                        except:
                            pass
                        try:
                            space.index(spiltSpace[cpt+1])
                            result.append(word)
                        except:
                            pass
                    else:
                        result.append(word)
                    cpt+=1
                line.line="".join(result)

                if line.line=="":
                    continue
                ret+=line.line+""
                
        else:
            for line in self.lines:
                if not line:
                    continue
                for doc in line.doc:
                    ret+=("\t"*(line.level-2))+doc+"\n"
                ret+=("\t"*(line.level-2))+line.line+"\n"
        self.result=ret
        
        return self.result
    
    def getHeader(self):
        return ""
    
    def getFooter(self):
        ret=""
        for extDesc in self.extends:
            s=""
            subDesc=extDesc
            while subDesc.valueType:
                s+=subDesc.valueType.getName()+'.prototype,'
                subDesc=subDesc.valueType
            #if Config.COMPRESSION>2:
            #    ret+='e_('+extDesc.getName()+'.prototype,'+s[:-1]+');'    
            if Config.COMPRESSION:
                ret+='jslib.oop.extends_prototype('+extDesc.getName()+'.prototype,'+s[:-1]+');'
            else:
                ret+='jslib.oop.extends_prototype('+extDesc.getName()+'.prototype,'+s[:-1]+');\n'
            
        return ret
    
    def write(self,descs):
        prev=None
        ret=[]
        
        for desc in descs:
            if not hasattr(self,"write_"+desc.objectType):
                continue
            
            lines=getattr(self,"write_"+desc.objectType)(desc)
            if lines==-1:
                continue
            if lines:
                if type(lines)==list:
                    for line in lines:
                        line.desc=desc
                        line.level+=desc.level
                        ret.append(line)
                else:
                    line=lines
                    line.level+=desc.level
                    line.desc=desc
                    ret.append(line)
                    
            if len(self.addline):
                ret+=self.addline
                self.addline=[]
            if len(desc.getChilds()):
                ret+=self.write(desc.getChilds())
            if lines and line.desc.block:
                ret+=self.write_close(desc,descs)
            prev=desc
        return ret
    
    def writeParam(self,childs,optional=True):
        args=""
        doc=""
        cpt=0
        for arg in childs:
            if arg.access=="optional" and arg.value!="null":
                args+=arg.name+", "
                result=JSSubWrite(arg,True,self._path).result
                if result[0].line==self.getDefaultValue(arg.valueType):
                    continue
                if optional:
                    line=Line("if("+arg.name+"==undefined) "+arg.name+" ="+result[0].line+";",arg.parent.level+1,arg)
                    self.addline.append(line)
            elif arg.access=="list":
                line2=Line()
                line=Line("for (var i="+str(cpt)+"; i<arguments.length;i++) "+arg.name+".push("+arg.value+");",arg.parent.level+1,arg)
                self.addline.append(Line(arg.name+"=[]",arg.parent.level+1))
                self.addline.append(line)
            else:
                args+=arg.name+", "
            cpt+=1
            
        return args[:-2]
    
    def writeDoc(self,desc):
        if Config.COMPRESSION:
            return []
        if desc.replaceDesc:
            desc=desc.replace
        ret=["/**"]
        if desc.doc and desc.doc.has_key("@main"):
            docs=desc.doc["@main"]
            for doc in docs:
                ret.append(" * "+doc)
        if desc.objectType=="property":
            ret.append(" * @property {"+desc.valueType+"}")
        if desc.objectType=="method" or desc.objectType=="function" or desc.objectType=="setter" or desc.objectType=="getter":
            for arg in desc.subDescription:
                if arg.valueType!="":
                    if arg.doc:
                        docs=arg.doc
                    else:
                        docs=[""]
                    if arg.access=="optional":
                        ret.append(" * @param {"+translateType(arg.valueType)+"}"+" ["+arg.name+"]\t"+docs[0])
                    else:
                        ret.append(" * @param {"+translateType(arg.valueType)+"}"+" "+arg.name+"\t"+docs[0])
                    for doc in docs[1:]:
                        ret.append(" * "+doc)
            
            if desc.valueType!="" and desc.valueType!="void" and desc.objectType!="setter" :
                if desc.doc and desc.doc.has_key("@return"):
                    docs=desc.doc["@return"]
                else:
                    docs=[""]
                ret.append(" * @returns {"+translateType(desc.valueType)+"}\t"+docs[0])
                for doc in docs[1:]:
                    ret.append(" * "+doc)
        
        if desc.objectType=="class" and desc.valueType:
            ret.append(" * @extends {"+desc.valueType.name+"}")
            
        if desc.access:
            ret.append(" * @"+desc.access)
        
        if desc.static:
            ret.append(" * @static")
        
        #if desc.constructor:
        #    ret.append(" * @constructor")
        
        ret.append(" */")
        if len(ret)==2:
            return []
        return ret
    
    def write_package(self,desc):
        self._package=desc
        return None
    
    def write_line(self,desc):
        if self.className==None and self.header==False:
            return
        
        if desc.subDescription and len(desc.subDescription):
            ret=JSSubWrite(desc,True,self._path).result
        else:
            ret=[Line()]
            ret[0].line=desc.line
        if desc.replaceDesc:
            ret[0].doc=self.writeDoc(desc.replaceDesc)
        if desc.getChilds():
            desc.block=True
        if desc.block:
            ret.append(Line())
            ret[-1].line="{"
        
        return ret
    
    def getDefaultValue(self,objectType):
        if objectType=="int":
            return "0"
        elif objectType=="uint":
            return "0"
        elif objectType=="Boolean":
            return "false"
        return "null"


class JSPrototype(JSGeneric):
    def __init__(self,desc,path_=None,mainScript=False):
        self._path=path_
        self.classAlone=True
        JSGeneric.__init__(self,desc,False,path_,mainScript)
        
    def getResult(self):
        if self.classAlone:
            return ""
        else:
            return JSGeneric.getResult(self)
    
    def write_close(self,desc,descs):
        line=[Line()]
        if desc.parent.objectType=="class":
            line[0].line="},"
        else:
            line[0].line="}"
        
           
        
        line[0].level=desc.level
        line[0].desc=desc
        
        #if desc.constructor and desc.objectType=="method":
        #    line.insert(0,Line("return this;",desc.level+1,desc)) 
        
        return line

    def write_class(self,desc):
        ret=[Line(),Line("{",desc.level-2,desc)]
        #ret.doc=self.writeDoc(desc)
        self.className=desc.name
        ret[0].line=desc.getName()+".prototype = "
        #if desc.valueType:
        #    desc.childs+=desc.valueType.childs
        #if desc.valueType:
        #    ret+=self.write(desc.valueType.childs)
        if Config.DEBUG:
            d=Description()
            d.name="__name__:"
            d.objectType="property"
            d.value='"'+desc.name+'"'
            desc.childs=[d]+desc.childs
        if desc.constructor==False:
            d=Description()
            d.name=Config.CONSTRUCTOR_NAME
            d.objectType="method"
            d.level=desc.level+1
            desc.childs.sort(sortProperty)
        
        return ret
    
    def write_getter(self,desc):
        self.classAlone=False
        ret=Line()
        ret.doc=self.writeDoc(desc)
        ret.line+='get '+desc.name+"() {"
        return ret
    
    def write_setter(self,desc):
        self.classAlone=False
        ret=Line()
        ret.doc=self.writeDoc(desc)
        ret.line+='set '+desc.name+"("+self.writeParam(desc.subDescription)+") {"
        return ret

    def write_method(self,desc):
        if desc.static:
            return -1
        name=desc.name
        self.classAlone=False
        if self.className==desc.name:
            desc.constructor=True
            self.construct=True
            name=Config.CONSTRUCTOR_NAME
        else:
            name=desc.getName()
        
        ret=[Line(),Line()]
        ret[1].line+=name+" : function ("+self.writeParam(desc.subDescription)+") {";
        ret[1].doc=self.writeDoc(desc)
        
        if desc.constructor and not desc.hasSuper and desc.parent.valueType:
            d=Description()
            d.objectType="line"
            d.parent=desc
            d.level=desc.level+1
            d.subDescription=[Description(),"();"]
            d.subDescription[0].objectType="super"
            d.subDescription[0].parent=d
            desc.childs.insert(0, d)
            
        return ret
    
    def write_property(self,desc):
        if desc.static or not Config.PROPERTY_PROTO:
            return -1
        ret=Line()
        ret.doc=self.writeDoc(desc)
        name=desc.getName()
        
        if not desc.value:
            ret.line=""+name+" : "+self.getDefaultValue(desc.valueType)+","
        elif type(desc.value)==str:
            ret.line=""+name+desc.value.replace("=",":")+","
        elif type(desc.value)==list:
            ret.line=""+name+JSSubWrite(desc,False,self._path).read(desc.value).replace("=",":")+","
        else:
            ret.line=""+name+" : "+desc.value.name+","
        
        return ret
    
    





class JSClass(JSGeneric):
    def __init__(self,desc,path_=None,mainScript=False):
        global renameId
        self._path=path_
        self.construct=False
        renameId=0;
        self.closeClass=None
        JSGeneric.__init__(self,desc,True,path_,mainScript)
        
        
        
    def write_import(self,desc):
        if Config.MERGE_FILE or (type(desc.valueType)!=str and not desc.valueType.export):
            return -1
        ret=Line()
        path=desc.name.replace('.','/')+'.js'
        ret.line='jslib.include_js("'+Config.FOLDER+path+'");'
        return ret
        
        
    def write_close(self,desc,decs):
        line=[Line(),Line()]
        
        
            
        line[0].line="}"
        
        if self.closeClass and (Config.COMPRESSION<4 or self.mainScript) and desc.objectType=="class":
            ret.append(self.closeClass)
            
        line[0].desc=desc
        
        return line
        
    def write_class(self,desc):
        global renameIds
        self.className=desc.name
        ret=[Line(),Line(),Line(),Line()]
        add=False
        if Config.COMPRESSION>2:
            if desc.rename:
                n=desc.rename
            else:
                n=getShrinkName(desc.name,desc.parent,"world","$")
            
            l3=Line()
            l3.line=desc.name+"="+n
            
            if len(l3.line)<desc.name*desc.use or Config.COMPRESSION>3:
                REPLACE_COMPRESSION[desc.name]=n
                desc.rename=n
                self.closeClass=l3
                add=True
                
        
        if not renameIds.has_key(desc.name):
            renameIds[desc.name]=[0]
        
        
        
        ret[1].line+="function "+desc.getName()+" ("+self.writeParam(desc.subDescription,False)+")"
        #ret[1].line+="function "+desc.name+" ()"
        ret[2].line="{"
        if desc.constructor:
            ret[3].line="this.__init__("+self.writeParam(desc.subDescription,False)+");"
        ret[3].level=1;
        ret[1].doc=self.writeDoc(desc)
        if desc.valueType:
            if Config.MERGE_FILE:
                self.extends.append(desc)
                subDesc=desc
                while subDesc.valueType:
                    renameIds[subDesc.valueType.name]=renameIds[desc.name]
                    subDesc=subDesc.valueType
            else:
                s=""
                subDesc=desc
                while subDesc.valueType:
                    s+=subDesc.valueType.name+'","'
                    renameIds[subDesc.valueType.name]=renameIds[desc.name]
                    subDesc=subDesc.valueType
                    
                ret[0].line='jslib.oop.extends_js("'+desc.getName()+'","'+s[:-3]+'");'
                ret=[Line()]+ret
        
        #l=Line()
        #l.line="}"
        #ret.append(l)
        
        
        return ret
    
    def write_property(self,desc):
        if desc.static or Config.PROPERTY_PROTO:
            return -1
        ret=Line()
        ret.doc=self.writeDoc(desc)
        name=desc.getName()
        
        if not desc.value:
            ret.line="this."+name+" = "+self.getDefaultValue(desc.valueType)+";"
        elif type(desc.value)==str:
            ret.line="this."+name+desc.value+";"
        elif type(desc.value)==list:
            ret.line="this."+name+JSSubWrite(desc,False,self._path).read(desc.value)+";"
        else:
            ret.line="this."+name+" = "+desc.value.name+";"
        
        return ret

 

class JSStatic(JSGeneric):
    def __init__(self,desc,path_=None,mainScript=False):
        self._path=path_
        self.construct=False
        JSGeneric.__init__(self,desc,False,self._path,mainScript)
        
    def write_class(self,desc):
        
        self.className=desc.getName()
        return None
    
    def write_method(self,desc):
        if not desc.static:
            return -1
        ret=[Line(),Line("{")]
        if self.className:
            ret[0].line=self.className+"."
        ret[0].doc=self.writeDoc(desc)
        ret[0].line+=desc.name+" = function("+self.writeParam(desc.subDescription)+")"
        ret[0].level=-2
        ret[1].level=-2
        return ret
    
    def write_property(self,desc):
        if not desc.static:
            return -1
        ret=Line()
        if self.className:
            ret.line=self.className+"."
            
        ret.doc=self.writeDoc(desc)
        
        if not desc.value:
            ret.line+=desc.name+self.getDefaultValue(desc.valueType)+";"
        elif type(desc.value)==str:
            ret.line+=desc.name+desc.value+";"
        elif type(desc.value)==list:
            ret.line=self.className+"."+desc.name+JSSubWrite(desc,False,self._path).read(desc.value)+";"
        else:
            ret.line+=desc.name+" = "+desc.value.name+";"
        ret.level=-2
        return ret
    
    def write_line(self,desc):
        ret=JSGeneric.write_line(self,desc)
        if not ret or ret==-1:
            return ret
        #for line in ret:
        #    line.level-=1
        return ret
    
    def getDefaultValue(self,objectType):
        if objectType=="int":
            return " = 0"
        elif objectType=="uint":
            return " = 0"
        elif objectType=="Boolean":
            return " = false"
        return ""
        
    def write_close(self,desc,decs):
        line=[Line(),Line()]
        line[0].line="}"
        line[0].desc=desc
        line[0].level=desc.level
        return line
   
    
class JSSubWrite:
    def __init__(self,desc,autoRead=True,path=None):
        self._path=path
        self.desc=desc
        self._var=None
        self.breakFor=False    
        self.parent=self.desc.parent
        self.result=[Line()]
        if autoRead:
            self.result[0].line=self.read(self.desc.subDescription)
        
    def read(self,subDesc):
        self.preAnalyse()
        self.subDesc=subDesc
        self.string=""
        for i in range(len(subDesc)):
            self.current=i
            sub=subDesc[i]
            if type(sub)==str:
                if Config.COMPRESSION:
                    sub=self.compression(sub)
                sub2=self.findValueType(sub)
                
                if type(sub2)==str and sub2=="trace":
                    self.string+="jslib.output.log"
                    continue
                elif type(sub2)==str:
                    self.string+=sub2
                    continue
                else:
                    subDesc[i]=sub2
                    sub=sub2
                
            if hasattr(self,"write_"+sub.objectType):
                self.string+=getattr(self,"write_"+sub.objectType)(sub)
            else:
                self.string+=sub.name
            if self.breakFor:
                return self.string
        return self.string
    
    def compression(self,sub):
        subs=sub.split(".")
        for i in range(len(subs)):
            if Config.COMPRESSION>2:
                if subs[i]=="true":
                    subs[i]="!0"
                elif subs[i]=="false":
                    subs[i]="!1"
            if Config.COMPRESSION>2 and Config.MERGE_FILE:
                for ind in REPLACE_COMPRESSION:
                    if subs[i]==REPLACE_COMPRESSION[ind] and i==0:
                        subs[i]=ind
            
        return ".".join(subs)
    
    
    def preAnalyse(self):
        if self.desc.parent.name=="switch":
            try:
                self.desc.subDescription.index("case")
            except:
                try:
                    self.desc.subDescription.index("break")
                except:
                    self.desc.level+=1

    def findValueType(self,sub):
        if sub==" ":
            return sub
        elif sub=="is":
            print self._path,self.string,self.subDesc[self.current-2]
            n=self.subDesc[self.current-2]
            if  type(self.subDesc[self.current-2])!=str:
                n=self.subDesc[self.current-2].name
            
            self.string=self.string[:self.string.rfind(n)]
            
            ret="jslib.oop.isInstanceOf("+n+","+self.subDesc[self.current+2].valueType.getName()+")"

            self.subDesc[self.current+2]=""
            self.subDesc[self.current+1]=""
            self.subDesc[self.current-2]=""
            return ret
        elif sub=="as":
            self.subDesc[self.findNoSpace(self.current)]=""
            return ""
        
        sanalyse=sub
        subs=sub.split('.')
        if len(subs)>1:
            sanalyse=subs[0]
            if sanalyse=="this":
                sub=sub[5:]
                sanalyse=subs[1]
            
        child=self.parent.findChild(sanalyse)
        if not child:
            classDesc=self.parent.findParentByObjectType("class")
            if classDesc:
                child=classDesc.findChild(sanalyse)
            else:
                return sanalyse
        
        if not child and classDesc.valueType:
            child=classDesc.valueType.findChild(sanalyse)
        if child:
            desc=Description()
            desc.objectType="pointer"
            desc.parent=self.desc
            desc.name=sub
            desc.valueType=child
            
            return desc
        return sub

        
    def write_var(self,desc):
        if not self._var:
            self._var=desc
        return "var "+desc.name
    
    def write_pointer(self,desc):
        if not self._var:
            self._var=desc
        #if desc.valueType.static:
        #    return desc.name
        
        name=desc.name
        
        if desc.valueType and desc.valueType.objectType=="class" and name.find(desc.valueType.name)==0:
            
            explode=name.split(".")
            name=desc.valueType.getName()+"."+".".join(explode[1:])
            
            return name
        elif desc.valueType and desc.valueType.objectType=="property" and desc.valueType.static:
            return desc.findParentByObjectType("class").getName()+"."+name
        elif desc.valueType and desc.valueType.objectType=="property":
            ext=name.split(".")
            if len(ext)>1:
                ext="."+".".join(ext[1:])
            else:
                ext=""
            name=desc.valueType.getName()+ext
            #if desc.valueType.rename:
            #    name=desc.valueType.rename+ext
            #elif Config.COMPRESSION>1 and desc.valueType.access=="private":
            #    desc.valueType.rename=getShrinkName(name,desc.valueType.parent,desc.valueType.parent.name)
            #    name=desc.valueType.rename+ext
            return "this."+name
        elif desc.valueType and desc.valueType.objectType=="method":
            name=desc.valueType.getName()
            #if desc.valueType.rename:
            #    name=desc.valueType.rename
            #elif Config.COMPRESSION>1 and desc.valueType.access=="private":
            #    desc.valueType.rename=getShrinkName(name,desc.valueType.parent,desc.valueType.parent.name)
            #    name=desc.valueType.rename
            #FIXME Attention erreur si espace apres parentase
            if len(self.desc.subDescription)<self.current or self.desc.subDescription[self.findNoSpace(self.current+1)]!="(":
                return "jslib.delegate(this."+name+",this)"
            else:
                #return "delegate(this,this."+desc.name+")"
                return "this."+name
        elif desc.valueType and (desc.valueType.objectType=="setter" or desc.valueType.objectType=="getter"):
            return "this."+name
        else:
            return name
    
    
    
    def write_new(self,desc):
        s=self.subDesc.index(desc)+1
        #e=self.desc.subDescription.index(")",s)+1
        arg=self.read(self.subDesc[s:])
        #self.desc.subDescription=self.desc.subDescription[:s]+self.desc.subDescription[e:]
        
       
        
        if desc.valueType:
            desc=desc.valueType
        ret=self.translateNew(desc.name)
        if ret==desc.name and self.buildInType(desc.name):
            ret="new "+ret+arg
        elif ret==desc.name:
           #ret="new "+ret+"().__init__"+arg
            ret=desc.getName()
            ret=desc.getName()
            ret="new "+ret+""+arg
        elif desc.parent.objectType!="property":
            ret+=";"
        
            
            
        self.breakFor=True
            
        return ret
    
    def write_super(self,desc):
        if not desc.name:
            ret=desc.findParentByObjectType("class").valueType.getName()+".prototype.__init__"
            self.subDesc[self.current+1]=".call(this"
            
            if  len(self.subDesc)>self.current+2 and self.subDesc[self.current+2]!=")":
                self.subDesc[self.current+1]+=","
            elif  len(self.subDesc)<=self.current+2:
                self.subDesc[self.current+1]+=");"
            return ret
        else:
            if self.subDesc[self.findNoSpace(self.current+1)]=="(":
                self.subDesc[self.current+1]=".call(this"
                if self.subDesc[self.current+2]!=")":
                    self.subDesc[self.current+1]+=","
                return desc.findParentByObjectType("class").valueType.getName()+".prototype."+desc.name
            else:
                #if self.subDesc[self.current+2]!=")":
                #     self.subDesc[self.current+1]+=","
                print desc,desc.objectType,
                
                s=desc.findParentByObjectType("setter")
                g=desc.findParentByObjectType("getter")
                ret="Object.getOwnPropertyDescriptor("
                ret+=desc.findParentByObjectType("class").valueType.getName()+".prototype"
                ret+=',"'+desc.name+'").'
                if s:
                    cpt=1
                    while(self.subDesc[self.current+cpt]==" " or self.subDesc[self.current+cpt]=="="):
                        self.subDesc[self.current+cpt]=""
                        cpt+=1
                    self.subDesc.insert(self.current+cpt+1,");")
                    ret+="set.call(this,"
                    return ret
                elif g:
                    ret+="get.call(this)"
                    return ret
                else:
                    return desc.findParentByObjectType("class").valueType.getName()+".prototype."+desc.name
                #Object.getOwnPropertyDescriptor(Test.prototype,"patate").set.call(this,"a")
                
                #return desc.findParentByObjectType("class").valueType.getName()+".prototype."+desc.name
      
    def findNoSpace(self,start):
        while len(self.desc.subDescription)>start and self.desc.subDescription[start] is " ":
            start+=1
        return start
    
    
    def translateNew(self,objectType):
        objectType=translateType(objectType)
        if objectType=="Array":
            return "[]"
        elif objectType=="Object":
            return "{}"
        #elif self.buildInType(objectType):
        #    "new "+objectType+"()"
        return objectType;
    
    def buildInType(self,objectType):
        objectType=translateType(objectType)
        type_=["Array","Object","Date","XMLHttpRequest"]
        try:
            type_.index(objectType);
            return True
        except:
            return False
        
        

def getShrinkName(name,parentDesc,type_="global",add=""):
    
    global renameIds,renameString
    
   
    if not renameIds.has_key(type_):
        renameIds[type_]=[0]
    renameId=renameIds[type_][0]
    if len(name)<2:
        return name
    n=getSmallName(renameId)+add
    while parentDesc.findChildAndValueChild(n):
        renameId+=1
        n=getSmallName(renameId)+add
    renameId+=1
    renameIds[type_][0]=renameId
    
    
    
    #if add  is not "$":
    #    print parentDesc,n,name
    
    return n
        
def getSmallName(id_):
    global renameId,renameString
    n=renameString[id_%len(renameString)]
    num=id_/len(renameString)
    for i in range(num):
        n+=getSmallName(i)
    return n
    